package com.supercube.sport.yoga.controller;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.supercube.common.controller.BaseController;
import com.supercube.common.utils.DateUtils;
import com.supercube.common.utils.StringUtils;
import com.supercube.sport.yoga.bo.BookingCourseBO;
import com.supercube.sport.yoga.bo.BookingPersonalCourseBO;
import com.supercube.sport.yoga.bo.ClassTableInfoBO;
import com.supercube.sport.yoga.bo.CourseSupportCardInfoBO;
import com.supercube.sport.yoga.dao.CourseBasicInfoMapper;
import com.supercube.sport.yoga.domain.ClassInfoDTO;
import com.supercube.sport.yoga.domain.CoursesSupportedCardDTO;
import com.supercube.sport.yoga.service.BookingCourseService;
import com.supercube.sport.yoga.service.ClassTableInfo;
import com.supercube.sport.yoga.service.MemberCardService;
import com.supercube.sport.yoga.utils.ResultInfo;
import com.supercube.sport.yoga.utils.UserUtils;
import com.supercube.sport.yoga.vo.ClassTableInfoVO;
import com.supercube.sport.yoga.vo.CourseBasicInfoVO;
import com.supercube.sport.yoga.vo.CourseSupportCardInfoVO;
import com.supercube.sport.yoga.vo.MemberBookingCourseInfoVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/classTableInfo")
@Api(tags = "课程表管理")
public class ClassTableInfoController extends BaseController {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private ClassTableInfo classTableInfo;

    @Autowired
    private BookingCourseService bookingCourseService;

    @Autowired
    CourseBasicInfoMapper courseBasicInfoMapper;

    @Autowired
    MemberCardService memberCardService;

    @ApiOperation(value = "添加私教排期（保存课程表信息）", notes = "添加私教排期（保存课程表信息）")
    @PostMapping("/savePersonalClassTable")
    public ResultInfo savePersonalClassTableInfo(@RequestBody BookingPersonalCourseBO bo) {
        Integer integer = classTableInfo.savePersonalClassTable(bo);
        if (integer == 2) {
            return ResultInfo.failed("该时间段，教练已有排期");
        }
        return ResultInfo.success("保存成功");
    }


    @ApiOperation(value = "添加团课排期（保存课程表信息）", notes = "添加团课排期（保存课程表信息）")
    @PostMapping("/save")
    public ResultInfo saveClassTableInfo(@RequestBody List<BookingCourseBO> bos) {
        Integer integer = classTableInfo.saveClassTableInfo(bos);
        if (integer == 1) {
            ResultInfo.failed("该时间段，场地不可用");
        }
        if (integer == 2) {
            ResultInfo.failed("该时间段，教练已有排期");
        }
        return ResultInfo.success("保存成功");
    }

    @ApiOperation(value = "修改排期（修改课程表信息）", notes = "修改排期（修改课程表信息）")
    @PostMapping("/update")
    public ResultInfo updateClassTableInfo(@RequestBody ClassInfoDTO dto) {
        UserUtils.setLastModifyRecordBase(dto);
        int update = classTableInfo.update(dto);
        return ResultInfo.success("修改成功");
    }

    @ApiOperation(value = "删除课程表信息", notes = "删除课程表信息")
    @GetMapping("/delete")
    public ResultInfo deleteClassTableInfoById(@RequestParam("id") String id) {
        int count = deleteClassTableInfoByClassTableId(id);
        if (count < 0) {
            return ResultInfo.failed("已存在预约课程，无法删除");
        }
        return ResultInfo.success("删除成功");
    }

    @ApiOperation(value = "批量删除课程表信息", notes = "批量删除课程表信息")
    @GetMapping("/batchDelete")
    public ResultInfo batchDeleteClassTableInfoById(@RequestParam("ids") String[] ids) {
        int success = 0;
        int failed = 0;
        for (String id : ids) {
            int count = deleteClassTableInfoByClassTableId(id);
            if (count < 0) {
                failed++;
            } else {
                success++;
            }
        }
        return ResultInfo.success("删除完成,成功:" + success + ",失败：" + failed);
    }

    private int deleteClassTableInfoByClassTableId(@RequestParam("id") String id) {
        int count = bookingCourseService.countBookingCourseInfoByClassId(id);
        if (count > 0) {
            /*ClassInfoDTO classInfoDTO = new ClassInfoDTO();
            classInfoDTO.setId(id);
            classInfoDTO.setStatus("2");
            classTableInfo.update(classInfoDTO);*/
            return -1;
        } else {
            return classTableInfo.deleteClassTableInfoById(id);
        }
    }

    @ApiOperation(value = "查询课程表信息", notes = "根据课时id查询该课时信息、预约汇总情况")
    @PostMapping("/queryClassTableInfoById")
    public ResultInfo queryClassTableInfoById(@RequestParam("id") String id) {
        ClassTableInfoVO vo = classTableInfo.queryClassTableInfoById(id);
        return ResultInfo.success(vo);
    }

    @ApiOperation(value = "查询课程表信息预约详情", notes = "根据课时id查询该课时预约详情，会员预约信息")
    @PostMapping("/queryMemberBookingCourseInfoByClassId")
    public ResultInfo queryMemberBookingCourseInfoByClassId(@RequestBody Map<String, String> map) {
        List<MemberBookingCourseInfoVO> vos = bookingCourseService.queryMemberBookingCourseInfoByClassId(map.get("classId"));
        return ResultInfo.success(vos);
    }

    @ApiOperation(value = "查询课程表信息详情列表", notes = "查询课程表信息详情列表" +
            "{venueId:场馆id（必填）；coachId:教练id;type:[1:列表(指定天)，2：周课表；3：月课表];" +
            "startDate：开始时间[根据type，1/2:yyyy-MM-DD;3:yyyy-MM]" +
            "classType:1:团课(包括小班课)；3：私教}")
    @PostMapping("/list")
    public ResultInfo queryClassTableInfoList(@RequestBody ClassTableInfoBO bo) {
        bo.setPageNum(null);
        bo.setPageSize(null);
        checkClassTableInfoBO(bo);
        List<ClassTableInfoVO> classTableInfoVOList = classTableInfo.queryClassTableInfoList(bo).stream().map(classTableInfo -> {
            String endTime = classTableInfo.getEndTime();
            if (StringUtils.isEmpty(endTime)) {
                endTime = DateUtils.getDate(
                        DateUtils.formatStrDateHHmm(classTableInfo.getOpeningTimeHour() + ":" + classTableInfo.getOpeningTime()),
                        "HH:mm",
                        Integer.parseInt(StringUtils.getDefault(classTableInfo.getCourseDuration(), "60")),
                        Calendar.MINUTE);
            }
            classTableInfo.setTimePeriod(classTableInfo.getOpeningTimeHour() + ":" + classTableInfo.getOpeningTime() + "~" + endTime);
            return classTableInfo;
        }).collect(Collectors.toList());
        return ResultInfo.success(classTableInfoVOList);
    }

    private void checkClassTableInfoBO(@RequestBody ClassTableInfoBO bo) {
        // map key venueId:场馆id（必填）；coachId:教练id;
        // type:[1:列表(指定天)，2：周课表；3：月课表];startDate：开始时间[根据type，1/2:yyyy-MM-DD;3:yyyy-MM]

        String startDate = StringUtils.getDefault(bo.getStartDate(), DateUtils.getDate());
        String endDate = StringUtils.getDefault(bo.getEndDate(), DateUtils.getDate());
        String type = StringUtils.getDefault(bo.getType(), "1");
        String classType = StringUtils.getDefault(bo.getClassType(), "1");//1、2:团课；3：私教
        if (StringUtils.isEmpty(bo.getVenueId())) {
            bo.setUserId(getUserId());
        }
        switch (type) {
            case "1":
                endDate = startDate;
                break;
            case "2":
                endDate = DateUtils.getDate(DateUtils.getDateByYyyyMmDd(startDate), "yyyy-MM-dd", 6, Calendar.DAY_OF_MONTH);
                break;
            case "3":
                endDate = DateUtils.formatDate(DateUtils.getLastDayOfMonth(DateUtils.getDateByYyyyMmDd(startDate + "-01")));
                startDate = DateUtils.formatDate(DateUtils.getFirstDayDateOfMonth(DateUtils.getDateByYyyyMmDd(startDate + "-01")));
                break;
            default:
                ResultInfo.failed("失败");
                break;
        }
        if (StringUtils.isEmpty(bo.getClassId())) {
            bo.setStartDate(startDate);
            bo.setEndDate(endDate);
            bo.setClassType(classType);
        }
    }

    @ApiOperation(value = "查询课程表信息详情列表-分页", notes = "查询课程表信息详情列表-分页" +
            "{venueId:场馆id（必填）；coachId:教练id;type:[1:列表(指定天)，2：周课表；3：月课表];" +
            "startDate：开始时间[根据type，1/2:yyyy-MM-DD;3:yyyy-MM]" +
            "classType:1:团课(包括小班课)；3：私教}")
    @PostMapping("/listPage")
    public ResultInfo queryPageClassTableInfoList(@RequestBody ClassTableInfoBO bo) {

        checkClassTableInfoBO(bo);
        PageHelper.startPage(bo.getPageNum(), bo.getPageSize());
        List<ClassTableInfoVO> classTableInfoVOList = classTableInfo.queryClassTableInfoList(bo);
        classTableInfoVOList.stream().map(classTableInfo -> {
            classTableInfo.setTimePeriod(classTableInfo.getOpeningTimeHour() + ":" + classTableInfo.getOpeningTime() + "~"
                    + DateUtils.getDate(
                    DateUtils.formatStrDateHHmm(classTableInfo.getOpeningTimeHour() + ":" + classTableInfo.getOpeningTime()),
                    "HH:mm",
                    Integer.parseInt(StringUtils.getDefault(classTableInfo.getCourseDuration(), "60")),
                    Calendar.MINUTE));
            return classTableInfo;
        }).collect(Collectors.toList());
        PageInfo<ClassTableInfoVO> pageInfo = new PageInfo<>(classTableInfoVOList);
        return ResultInfo.success(pageInfo);
    }

    @ApiOperation(value = "复制课表", notes = "复制课表 venueId:场馆id（必填）；startDate:开始时间；" +
            "endDate:结束时间；nextStartDate:目标开始时间")
    @PostMapping("/copyClassTable")
    public ResultInfo copyClassTable(@RequestBody ClassTableInfoBO bo) {

        // map key venueId:场馆id（必填）；startDate:开始时间；endDate:结束时间；nextStartDate:目标开始时间
        bo.setPageNum(null);
        bo.setPageSize(null);
        String startDate = bo.getStartDate();
        String nextStartDate = bo.getNextStartDate();
        int distanceDays = DateUtils.getDistanceDays(startDate, nextStartDate);


        List<ClassTableInfoVO> classTableInfoVOList = classTableInfo.queryClassTableInfoList(bo);
        classTableInfoVOList.forEach(vo -> {
            if (vo.getCoachId() != null && StringUtils.isNotEmpty(vo.getCourseId()) && StringUtils.isNotEmpty(vo.getSiteId())) {
                ClassInfoDTO dto = new ClassInfoDTO();
                try {
                    BeanUtils.copyProperties(dto, vo);
                    if (vo.getCoachId() == null) {
                        dto.setCoachId(null);
                    }
                    String id = UUID.randomUUID().toString();
                    dto.setId(id);
                    dto.setDate(DateUtils.getDate(DateUtils.getDateByYyyyMmDd(vo.getDate()), "yyyy-MM-dd", distanceDays, Calendar.DAY_OF_MONTH));
                    classTableInfo.save(dto);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }
            }
        });
        return ResultInfo.success("复制成功！");
    }

    @ApiOperation(value = "根据课程id查询支持会员卡", notes = "根据课程id查询支持会员卡")
    @PostMapping("/queryAllCardByCourseId")
    public ResultInfo queryAllCardByCourseId(String courseId, String cardName, String cardType) {
        List<CourseSupportCardInfoVO> courseSupportCardInfoVOS = classTableInfo.queryAllCardByCourseId(courseId, cardName, cardType);
        return ResultInfo.success(courseSupportCardInfoVOS);
    }

    @ApiOperation(value = "根据课表id，添加支持会员卡", notes = "根据课表id，添加支持会员卡")
    @PostMapping("/saveSetCardByCourseId")
    public ResultInfo saveSetCardByCourseId(@RequestBody List<CourseSupportCardInfoBO> bos) {
        bos.forEach(bo -> {
            CoursesSupportedCardDTO dto = new CoursesSupportedCardDTO();
            try {
                BeanUtils.copyProperties(dto, bo);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            memberCardService.updateCoursesSupportedCard(Arrays.asList(dto), bo.getCardId());
        });
        return ResultInfo.success("保存成功");
    }

}
